#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <arpa/inet.h>

#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct addrinfo {
   union address {
      struct in_addr addr4;
      struct in6_addr addr6;
   } ip;

   int mask;
};

int main(int, char *[]);
void ipaddress(const char *);

int
main(int argc, char *argv[])
{
   if (argc == 2) {
      const char *entry = argv[1];
      ipaddress(entry);
      printf("%s\n", entry);
   }

   return 0;
}

void
ipaddress(const char *address) 
{
   int mask = 0, retval =0, v4 = 0;
   char *ptr = NULL, *ptr_s = NULL;
   const char *errstr;
   struct addrinfo addr;

   if ((ptr = strrchr(address, '/')) != NULL) {
      mask = strtonum(ptr + 1, 0, 128, &errstr);
      if (errstr) {
         errx(1, "prefixlen is %s: %s", errstr, ptr + 1);
      }
   }

   addr.mask = 0;
   if ((ptr_s = strdup(address)) == NULL)
      errx(1, "strdup()");

   retval = inet_net_pton(
         PF_INET, strsep(&ptr_s, "/"), &addr.ip.addr4, sizeof(struct in_addr));
   printf("%d:%d\n", retval, errno);
   if (retval < 0)  {
      retval = inet_net_pton(PF_INET6, strsep(&ptr_s, "/"), &addr.ip.addr6,
               sizeof(struct in6_addr));
      printf("%d:%d\n", retval, errno);
      if (retval < 0) {
         free(ptr_s);
         errx(1, "inet_pton");
      }
      else {
         if (mask > 128)
            warnx("invalid mask");
         else if (mask == 0)
            addr.mask = 128;
         else
            addr.mask = mask;
      }
   }
   else {
      if (mask > 32)
         warnx("invalid mask");
      else if (mask == 0)
         addr.mask = 32;
      else
         addr.mask = mask;
   }

   printf("%d\n", addr.mask);

   free(ptr_s);
}
